﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Linq.Expressions;
using XYAC.Framework.WohuaMesExtend.IHI.DataContext;
using XYAC.Framework.WohuaMesExtend.IHI.Extensions;
using XYAC.Framework.WohuaMesExtend.IHI.LocalData.Context;
using XYAC.Framework.WohuaMesExtend.IHI.LocalData.Models;
using XYAC.Framework.WohuaMesExtend.IHI.Models;
using XYAC.Framework.WohuaMesExtend.IHI.OracleRemoteDB;

namespace XYAC.Framework.WohuaMesExtend.IHI.Services
{
    public class LocalDataService : IDisposable
    {
        private const String __TABLE_DwlData = "DwlData";
        private const String __TABLE_LaserData = "LaserData";
        //private const String /*__TABLE_SpecVal*/ = "SpecVal";
        public LocalDataService(IOptionsMonitor<AppConfig> options, ILogger<LocalDataService> logger, IServiceProvider provider)
        {
            //this.Db = context;
            //this.PreDb = _preDb;
            //this.NextDb = _nextDb;
            //this.CurrentAccessDb = _currentAccessDb;
            //this.PreAccessDb = _preAccessDb;
            //this.RemoteDb = remoteDb;
            this.Provider = provider;
            this.Logger = logger;
            this.AppConfig = options;
        }

        public YB_PROCESS_STEP From(DwlData data)
        {
            return new YB_PROCESS_STEP
            {
                RECORD1 = data.ID.ToString(),
                RECORD_DATE = data.DTime,
                RECORD2 = data.MSecond.ToString(),
                PART_NUMBER = data.TypeName.ToString().ToString(),
                RECORD5 = data.UpSd.ToString(),
                RECORD6 = data.UpTol.ToString(),
                RECORD7 = data.UpOpVal.ToString(),
                RECORD8 = data.UpMidVal.ToString(),
                RECORD9 = data.UpDrVal.ToString(),
                RECORD10 = data.DownSd.ToString(),
                RECORD11 = data.DownTol.ToString(),
                RECORD12 = data.DownOpVal.ToString(),
                RECORD13 = data.DownMidVal.ToString(),
                RECORD14 = data.DownDrVal.ToString(),
                RECORD15 = data.JuanHao.ToString(),
                RECORD16 = data.IsChengeSpeed.ToString(),
                RECORD17 = data.SystemState,
                RECORD18 = data.TableName.ToString(), // 字面值
                RECORD19 = data.Group,
                EQP = AppConfig.CurrentValue.DetectionMachineNo,
                EQP_TYPE = "1",
                //PLAN_ID = data.PlanNo,
                RECEIVE_FLAG = data.Status.ToString(), // 默认值 'PENDING'
            };
        }
        public YB_PROCESS_STEP From(LaserData data)
        {
            return new YB_PROCESS_STEP
            {
                RECORD1 = data.ID.ToString(),
                RECORD_DATE = data.DTime,
                RECORD56 = data.Group.ToString(),

                PART_NUMBER = data.TypeName.ToString().ToString(),
                //PART_NUMBER = data.SpecNo.ToString().ToString(),
                RECORD4 = data.SdVal.ToString(),
                RECORD5 = data.Tol.ToString(),
                RECORD6 = data.OpsVal.ToString(),
                RECORD7 = data.OpVal.ToString(),
                RECORD8 = data.MidVal.ToString(),
                RECORD9 = data.DrVal.ToString(),
                RECORD10 = data.DrsVal.ToString(),
                RECORD11 = data.SdWidth.ToString(),
                RECORD12 = data.AllWidth.ToString(),
                RECORD13 = data.WidthTol.ToString(),
                RECORD14 = data.JuanHao.ToString(),
                RECORD15 = data.IsChengeSpeed.ToString(),
                RECORD16 = data.DBW30.ToString(),
                RECORD17 = data.DBW32.ToString(),
                RECORD18 = data.DBW34.ToString(),
                RECORD19 = data.DBW36.ToString(),
                RECORD20 = data.DBW38.ToString(),
                RECORD21 = data.DBW40.ToString(),
                RECORD22 = data.DBW42.ToString(),
                RECORD23 = data.DBW44.ToString(),
                RECORD24 = data.DBW46.ToString(),
                RECORD25 = data.DBW48.ToString(),
                RECORD26 = data.DBW50.ToString(),
                RECORD27 = data.DBW52.ToString(),
                EQP = this.AppConfig.CurrentValue.DetectionMachineNo,
                EQP_TYPE = "2",
                RECORD29 = data.TableName.ToString(), // 字面值
                //PLAN_ID = data.PlanNo,
                RECEIVE_FLAG = data.Status.ToString(), // 字面值
                //RECORD30 = data.Sn
            };
        }

        public IServiceProvider Provider { get; }

        //public LocalDataContext Db { get; }
        //public LocalYesterdayDataContext PreDb { get; }
        //public LocalTomorrowDataContext NextDb { get; }
        //public AccessIHIDbContext CurrentAccessDb { get; }
        //public AccessIHIYesterdayDbContext PreAccessDb { get; }
        //public OracleMesContext RemoteDb { get; }
        public ILogger<LocalDataService> Logger { get; }
        public IOptionsMonitor<AppConfig> AppConfig { get; }
        public int UploadPageSize { get; private set; } = 30;

        internal int SyncNewData()
        {

            int ret = 0;
            using (var scope = this.Provider.CreateScope())
            {
                var CurrentAccessDb = scope.ServiceProvider.GetService<AccessIHIDbContext>();
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var PreDb = scope.ServiceProvider.GetService<LocalYesterdayDataContext>();
                var PreAccessDb = scope.ServiceProvider.GetService<AccessIHIYesterdayDbContext>();


                if (CurrentAccessDb.GetDbFileCreated())
                {
                    ret += SyncNewDataDwlDataDetails(CurrentAccessDb, Db);
                    ret += SyncNewDataLaserDataDetails(CurrentAccessDb, Db);
                }

                /*
                sfliu 2025年3月5号 注释，原因：客户反映说昨天的数据，为什么今天才传，所以把昨天的数据同步移除掉了
                    ，仅传送当前的数据，当前的数据滚动传送的话，并不存在昨天的数据之说。

                if (PreAccessDb.GetDbFileCreated())
                {
                    ret += SyncNewDataDwlDataDetails(PreAccessDb, PreDb);
                    ret += SyncNewDataLaserDataDetails(PreAccessDb, PreDb);
                }
                */
            }

            return ret;
        }

        private int SyncNewDataLaserDataDetails(AccessIHIYesterdayDbContext accessDb, LocalYesterdayDataContext db)
        {
            int ret = 0;
            using (var trans = db.Database.BeginTransaction())
            {
                try
                {
                    var maxKey = 0;
                    if (db.LocalRecord.Count(T => T.TableName == __TABLE_LaserData) > 0)
                        maxKey = db.LocalRecord.Where(T => T.SourceKey != null && T.TableName == __TABLE_LaserData).ToList().Max(T => Convert.ToInt32(T.SourceKey));
                    var accessLaserData = accessDb.LaserData.Where(T => T.ID >= maxKey).ToList();

                    var recordList = accessLaserData.AsParallel().Select((T) =>
                    {
                        var json = JsonSerializeHelper.SerializeObjectToJson(T);
                        var crc = CrcCalculator.ComputeCrc128(json).ToString();
                        var record = new LocalRecord()
                        {
                            ProductionShift = T.Group,
                            TableName = __TABLE_LaserData,
                            LastSyncDate = DateTime.Now,
                            Sn = null,
                            LastSyncResult = false,
                            LastSyncExceptionMsg = null,
                            MachineName = this.AppConfig.CurrentValue.DetectionMachineNo,
                            SourceHash = crc,
                            SourceKey = T.ID.ToString(),
                            SourceDataJson = json,
                            SpecInfo = T.TypeName
                        };
                        return record;
                    }).ToList();

                    db.AddRange(recordList);

                    int tempRet = db.SaveChanges();
                    trans.Commit();
                    ret = tempRet;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Logger?.LogError($"查询昨日数据出现异常:{ex.Message}|{ex.StackTrace}");

                }
            }
            return ret;
        }

        private int SyncNewDataLaserDataDetails(AccessIHIDbContext accessDb, LocalDataContext db)
        {
            int ret = 0;
            using (var trans = db.Database.BeginTransaction())
            {
                try
                {
                    var maxKey = 0;
                    if (db.LocalRecord.Count(T => T.TableName == __TABLE_LaserData) > 0)
                        maxKey = db.LocalRecord.Where(T => T.SourceKey != null && T.TableName == __TABLE_LaserData).ToList().Max(T => Convert.ToInt32(T.SourceKey));
                    var accessLaserData = accessDb.LaserData.Where(T => T.ID >= maxKey).ToList();

                    var recordList = accessLaserData.AsParallel().Select((T) =>
                    {
                        var json = JsonSerializeHelper.SerializeObjectToJson(T);
                        var crc = CrcCalculator.ComputeCrc128(json).ToString();
                        var record = new LocalRecord()
                        {
                            ProductionShift = T.Group,
                            TableName = __TABLE_LaserData,
                            LastSyncDate = DateTime.Now,
                            Sn = null,
                            LastSyncResult = false,
                            LastSyncExceptionMsg = null,
                            MachineName = this.AppConfig.CurrentValue.DetectionMachineNo,
                            SourceHash = crc,
                            SourceKey = T.ID.ToString(),
                            SourceDataJson = json,
                            SpecInfo = T.TypeName
                        };
                        return record;
                    }).ToList();

                    db.AddRange(recordList);

                    int tempRet = db.SaveChanges();
                    trans.Commit();
                    ret = tempRet;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Logger?.LogError($"查询当前数据出现异常:{ex.Message}|{ex.StackTrace}");

                }
            }
            return ret;
        }

        private CrcCalculator CrcCalculator = new CrcCalculator();
        private int SyncNewDataDwlDataDetails(AccessIHIDbContext accessDb, LocalDataContext db)
        {
            int ret = 0;
            using (var trans = db.Database.BeginTransaction())
            {
                try
                {
                    var maxKey = 0;

                    var localDataCount = db.LocalRecord.Count(T => T.TableName == __TABLE_DwlData);
                    if (localDataCount > 0)
                        maxKey = db.LocalRecord.Where(T => T.SourceKey != null && T.TableName == __TABLE_DwlData).ToList().Max(T => Convert.ToInt32(T.SourceKey));
                    var accessDwlData = accessDb.DwlData.Where(T => T.ID >= maxKey).ToList();

                    var recordList = accessDwlData.AsParallel().Select((T) =>
                    {
                        var json = JsonSerializeHelper.SerializeObjectToJson(T);
                        var crc = CrcCalculator.ComputeCrc128(json).ToString();
                        var record = new LocalRecord()
                        {
                            ProductionShift = T.Group,
                            TableName = __TABLE_DwlData,
                            LastSyncDate = DateTime.Now,
                            Sn = null,
                            LastSyncResult = false,
                            LastSyncExceptionMsg = null,
                            MachineName = this.AppConfig.CurrentValue.DetectionMachineNo,
                            SourceHash = crc,
                            SourceKey = T.ID.ToString(),
                            SourceDataJson = json,
                            SpecInfo = T.TypeName
                        };
                        return record;
                    }).ToList();

                    db.AddRange(recordList);

                    int tempRet = db.SaveChanges();
                    trans.Commit();
                    ret = tempRet;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Logger?.LogError($"查询当前数据出现异常:{ex.Message}|{ex.StackTrace}");

                }
            }
            return ret;
        }

        private int SyncNewDataDwlDataDetails(AccessIHIYesterdayDbContext accessDb, LocalYesterdayDataContext db)
        {
            int ret = 0;
            using (var trans = db.Database.BeginTransaction())
            {
                try
                {
                    var maxKey = 0;
                    var localDataCount = db.LocalRecord.Count(T => T.TableName == __TABLE_DwlData);

                    if (localDataCount > 0)
                        maxKey = db.LocalRecord.Where(T => T.SourceKey != null && T.TableName == __TABLE_DwlData).ToList().Max(T => Convert.ToInt32(T.SourceKey));
                    var accessDwlData = accessDb.DwlData.Where(T => T.ID >= maxKey).ToList();

                    var recordList = accessDwlData.AsParallel().Select((T) =>
                    {
                        var json = JsonSerializeHelper.SerializeObjectToJson(T);
                        var crc = CrcCalculator.ComputeCrc128(json).ToString();
                        var record = new LocalRecord()
                        {
                            ProductionShift = T.Group,
                            TableName = __TABLE_DwlData,
                            LastSyncDate = DateTime.Now,
                            Sn = null,
                            LastSyncResult = false,
                            LastSyncExceptionMsg = null,
                            MachineName = this.AppConfig.CurrentValue.DetectionMachineNo,
                            SourceHash = crc,
                            SourceKey = T.ID.ToString(),
                            SourceDataJson = json,
                            SpecInfo = T.TypeName
                        };
                        return record;
                    }).ToList();

                    db.AddRange(recordList);

                    int tempRet = db.SaveChanges();
                    trans.Commit();
                    ret = tempRet;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    Logger?.LogError($"查询昨日数据出现异常:{ex.Message}|{ex.StackTrace}");

                }
            }
            return ret;
        }

        internal bool CreateDb()
        {
            var ret = false;
            try
            {
                using (var scope = this.Provider.CreateScope())
                {
                    var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                    Db.GetDbFileCreated();
                    ret = Db.Database.EnsureCreated();
                    Db.Database.ExecuteSqlRaw("PRAGMA journal_mode=MEMORY;");
                    Db.Database.CloseConnection();
                }
            }
            catch (Exception ex)
            {
                Logger?.LogError("创建当前数据库失败", ex);

            }
            return ret;
        }
        internal bool CreatePreDb()
        {
            var ret = false;
            try
            {
                using (var scope = this.Provider.CreateScope())
                {
                    var PreDb = scope.ServiceProvider.GetService<LocalYesterdayDataContext>();
                    PreDb.GetDbFileCreated();
                    ret = PreDb.Database.EnsureCreated();
                    PreDb.Database.ExecuteSqlRaw("PRAGMA journal_mode=MEMORY;");
                    PreDb.GetDbFileCreated();
                    PreDb.Database.CloseConnection();
                }
            }
            catch (Exception ex)
            {
                Logger?.LogError("创建前一日数据库失败", ex);

            }
            return ret;
        }

        internal bool CreateNextDb()
        {
            var ret = false;
            try
            {
                using (var scope = this.Provider.CreateScope())
                {
                    var NextDb = scope.ServiceProvider.GetService<LocalTomorrowDataContext>();
                    NextDb.GetDbFileCreated();
                    ret = NextDb.Database.EnsureCreated();
                    NextDb.Database.ExecuteSqlRaw("PRAGMA journal_mode=MEMORY;");
                    NextDb.Database.CloseConnection();
                }
            }
            catch (Exception ex)
            {
                Logger?.LogError("创建次日数据库失败", ex);
            }
            return ret;
        }

        internal LocalRecord? GetFirstLaserRecordData(Func<LocalRecord, bool> filterCondition = null)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                if (filterCondition != null)
                {
                    return Db.LocalRecord.OrderByDescending(T => T.LastSyncDate).Where(T => T.TableName == __TABLE_LaserData).FirstOrDefault(filterCondition);
                }
                return Db.LocalRecord.OrderByDescending(T => T.LastSyncDate).FirstOrDefault(T => T.TableName == __TABLE_LaserData);
            }

        }
        internal LocalRecord? GetFirstDwlRecordData(Func<LocalRecord, bool> filterCondition = null)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                if (filterCondition != null)
                {
                    return Db.LocalRecord.OrderByDescending(T => T.LastSyncDate).Where(T => T.TableName == __TABLE_DwlData).FirstOrDefault(filterCondition);
                }
                return Db.LocalRecord.OrderByDescending(T => T.LastSyncDate).FirstOrDefault(T => T.TableName == __TABLE_DwlData);

            }
        }


        internal IEnumerable<string> GetDistinceSpecInfos()
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                return Db.LocalRecord.Select(T => T.SpecInfo).Distinct().ToList();
            }
        }

        internal int DeleteSpecInfoSyncMappingEntity(IEnumerable<string> preRemoveSpecKey)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var specs = Db.SpecInfoSyncMapping.Where(T => preRemoveSpecKey.Contains(T.SpecName));
                Db.SpecInfoSyncMapping.RemoveRange(specs);

                return Db.SaveChanges();
            }
        }

        internal IEnumerable<SpecInfoSyncMapping> GetSpecInfoSyncMappingEntity(string[] findedSpecNames)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var specs = Db.SpecInfoSyncMapping.Where(T => findedSpecNames.Contains(T.SpecName));

                return specs;
            }
        }

        internal SpecInfoSyncMapping GetSpecInfoSyncMappingByName(string typeName)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var specs = Db.SpecInfoSyncMapping.FirstOrDefault(T => typeName == T.SpecName);

                return specs;
            }
        }

        internal int Update(SpecInfoSyncMapping findedMapping)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                Db.Update(findedMapping);
                return Db.SaveChanges();
            }
        }

        internal int Add(SpecInfoSyncMapping mappingEntity)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                Db.Add(mappingEntity);
                return Db.SaveChanges();
            }
        }

        internal int DeleteSpecInfoSyncMapping(IEnumerable<string> preRemoveSpecKey)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var specinfos = Db.SpecInfoSyncMapping.Where(T => preRemoveSpecKey.Contains(T.SpecName));
                Db.RemoveRange(specinfos);
                return Db.SaveChanges();
            }
        }

        internal IEnumerable<SpecInfoSyncMapping> GetSpecInfoSyncMapping(string[] findedSpecNames)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var specinfos = Db.SpecInfoSyncMapping.Where(T => findedSpecNames.Contains(T.SpecName));
                return specinfos;
            }
        }

        internal int Add(LocalRecord localRecord)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                Db.Add(localRecord);
                return Db.SaveChanges();
            }
        }

        internal int RemoveTimeovered(int days)
        {
            int ret = 0;
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                // 计算30天前的日期
                var thresholdDate = DateTime.Now.AddDays(-30);

                // 查询出 LastSyncDate 在30天前的记录
                var oldRecords = Db.LocalRecord
                                        .Where(record => record.LastSyncDate.HasValue && record.LastSyncDate.Value < thresholdDate)
                                        .ToList();
                var oldInspect = Db.YB_LOT_INSPECT
                                        .Where(record => record.PLAN_DATE.HasValue && record.PLAN_DATE.Value < thresholdDate)
                                        .ToList();

                if (oldRecords.Any())
                {
                    // 删除这些记录
                    Db.LocalRecord.RemoveRange(oldRecords);

                }
                if (oldInspect.Any())
                {
                    // 删除这些记录
                    Db.YB_LOT_INSPECT.RemoveRange(oldInspect);
                }
                // 保存更改
                ret = Db.SaveChanges();
                return ret;
            }
        }

        internal LocalRecord GetLocalDataFirstOrDefault(Func<LocalRecord, bool> conditions)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                return Db.LocalRecord.FirstOrDefault(conditions);
            }
        }

        internal int Update(LocalRecord findedRecord)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                var entity = Db.LocalRecord.FirstOrDefault(T => T.Guid == findedRecord.Guid);
                Db.Entry(entity).CurrentValues.SetValues(findedRecord);
                Db.Entry(entity).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
                return Db.SaveChanges();
            }
        }

        internal int GetCount<T>() where T : class, new()
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                return Db.Set<T>().Count();
            }
        }
        internal IEnumerable<T> GetPage<T>(int pageIndex, int pageSize,
      List<Expression<Func<T, bool>>> filterCondition = null,
      List<Expression<Func<T, object>>> orderConditions = null,
      List<Expression<Func<T, object>>> orderConditionDescs = null)
      where T : class, new()
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                IQueryable<T> data = Db.Set<T>();

                // 过滤条件
                if (filterCondition != null)
                {
                    foreach (var condition in filterCondition)
                    {
                        data = data.Where(condition);
                    }
                }

                // 排序条件
                bool isOrdered = false;
                if (orderConditions != null && orderConditions.Count > 0)
                {
                    for (int i = 0; i < orderConditions.Count; i++)
                    {
                        if (i == 0)
                        {
                            data = data.OrderBy(orderConditions[i]);
                            isOrdered = true;
                        }
                        else
                        {
                            data = (data as IOrderedQueryable<T>).ThenBy(orderConditions[i]);
                        }
                    }
                }

                if (orderConditionDescs != null && orderConditionDescs.Count > 0)
                {
                    for (int i = 0; i < orderConditionDescs.Count; i++)
                    {
                        if (i == 0 && !isOrdered)
                        {
                            data = data.OrderByDescending(orderConditionDescs[i]);
                        }
                        else
                        {
                            data = (data as IOrderedQueryable<T>).ThenByDescending(orderConditionDescs[i]);
                        }
                    }
                }

                return data.Skip(pageIndex * pageSize).Take(pageSize).ToList();
            }
        }
        internal IEnumerable<T> GetPreDayPage<T>(int pageIndex, int pageSize,
      List<Expression<Func<T, bool>>> filterCondition = null,
      List<Expression<Func<T, object>>> orderConditions = null,
      List<Expression<Func<T, object>>> orderConditionDescs = null)
      where T : class, new()
        {
            using (var scope = this.Provider.CreateScope())
            {
                var PreDb = scope.ServiceProvider.GetService<LocalYesterdayDataContext>();
                IQueryable<T> data = PreDb.Set<T>();

                // 过滤条件
                if (filterCondition != null)
                {
                    foreach (var condition in filterCondition)
                    {
                        data = data.Where(condition);
                    }
                }

                // 排序条件
                bool isOrdered = false;
                if (orderConditions != null && orderConditions.Count > 0)
                {
                    for (int i = 0; i < orderConditions.Count; i++)
                    {
                        if (i == 0)
                        {
                            data = data.OrderBy(orderConditions[i]);
                            isOrdered = true;
                        }
                        else
                        {
                            data = (data as IOrderedQueryable<T>).ThenBy(orderConditions[i]);
                        }
                    }
                }

                if (orderConditionDescs != null && orderConditionDescs.Count > 0)
                {
                    for (int i = 0; i < orderConditionDescs.Count; i++)
                    {
                        if (i == 0 && !isOrdered)
                        {
                            data = data.OrderByDescending(orderConditionDescs[i]);
                        }
                        else
                        {
                            data = (data as IOrderedQueryable<T>).ThenByDescending(orderConditionDescs[i]);
                        }
                    }
                }

                return data.Skip(pageIndex * pageSize).Take(pageSize).ToList();
            }
        }

        internal SpecInfoSyncMapping GetFirstSpecInfoSyncMapping(Func<SpecInfoSyncMapping, bool> condition)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                return Db.SpecInfoSyncMapping.FirstOrDefault(condition);
            }
        }

        internal int UpdateRange(IEnumerable<LocalRecord> localPreInsert)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                foreach (var findedRecord in localPreInsert)
                {
                    var entity = Db.LocalRecord.FirstOrDefault(T => T.Guid == findedRecord.Guid);
                    Db.Entry(entity).CurrentValues.SetValues(findedRecord);
                    Db.Entry(entity).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
                }
                return Db.SaveChanges();
            }
        }

        internal IEnumerable<LocalRecord> GetLocalDatas(Func<LocalRecord, bool> func)
        {
            using (var scope = this.Provider.CreateScope())
            {
                var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                return Db.LocalRecord.Where(func).ToList();
            }
        }

        internal int UploadData()
        {
            int ret = 0;
            try
            {
                using (var scope = this.Provider.CreateScope())
                {
                    var Db = scope.ServiceProvider.GetService<LocalDataContext>();
                    var RemoteDb = scope.ServiceProvider.GetService<OracleMesContext>();
                    List<LocalRecord> localData = null;
                    using (var localTrans = Db.Database.BeginTransaction())
                    {

                        try
                        {
                            using (var remoteTrans = RemoteDb.Database.BeginTransaction())
                            {
                                try
                                {
                                    localData = Db.LocalRecord.Where(T => T.SourceKey != null && T.LastSyncResult != true).OrderBy(T => T.SourceKey).Take(this.UploadPageSize).ToList();
                                    if (localData is null || localData.Count == 0)
                                    {
                                        return 0;
                                    }
                                    var remotePreInsertData = ConvertToProcessStep(localData);
                                    RemoteDb.AddRange(remotePreInsertData);
                                    localData.ForEach(T =>
                                    {
                                        T.LastSyncResult = true;
                                        T.LastSyncDate = DateTime.Now;
                                    });
                                    Db.UpdateRange(localData);
                                    var localRet = Db.SaveChanges();
                                    var remoteRet = RemoteDb.SaveChanges();
                                    if (localRet == remoteRet)
                                    {
                                        localTrans.Commit();
                                        remoteTrans.Commit();
                                        ret = localRet;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    localTrans.Rollback();
                                    remoteTrans.Rollback();
                                    this.Logger?.LogError($"上传当日数据失败:{ex.Message}{ex.StackTrace}", ex.InnerException ?? ex);

                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Logger?.LogError($"上传当日数据失败:{ex?.InnerException?.Message ?? ex.Message}{ex.StackTrace}", ex.InnerException ?? ex);

                            localTrans.Rollback();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.Logger?.LogError($"上传当日数据失败:{ex?.InnerException?.Message ?? ex.Message}{ex.StackTrace}", ex);

            }
            return ret;
        }

        internal int UploadYesterdayData()
        {
            int ret = 0;

            try
            {
                using (var scope = this.Provider.CreateScope())
                {
                    var PreDb = scope.ServiceProvider.GetService<LocalYesterdayDataContext>();
                    var RemoteDb = scope.ServiceProvider.GetService<OracleMesContext>();

                    List<LocalRecord> localData = null;
                    using (var localTrans = PreDb.Database.BeginTransaction())
                    {
                        try
                        {

                            using (var remoteTrans = RemoteDb.Database.BeginTransaction())
                            {
                                try
                                {
                                    localData = PreDb.LocalRecord.Where(T => T.SourceKey != null && T.LastSyncResult != true).OrderBy(T => T.SourceKey).Take(this.UploadPageSize).ToList();
                                    if (localData is null || localData.Count == 0)
                                    {
                                        return 0;
                                    }
                                    var remotePreInsertData = ConvertToProcessStep(localData);
                                    RemoteDb.AddRange(remotePreInsertData);
                                    localData.ForEach(T =>
                                    {
                                        T.LastSyncResult = true;
                                        T.LastSyncDate = DateTime.Now;
                                    });
                                    PreDb.UpdateRange(localData);
                                    var localRet = PreDb.SaveChanges();
                                    var remoteRet = RemoteDb.SaveChanges();
                                    if (localRet == remoteRet)
                                    {
                                        localTrans.Commit();
                                        remoteTrans.Commit();
                                        ret = localRet;
                                    }
                                }
                                catch (Exception ex)
                                {
                                    localTrans.Rollback();
                                    remoteTrans.Rollback();
                                    this.Logger?.LogError($"上传昨日数据失败:{ex.Message}{ex.StackTrace}", ex);

                                    throw ex;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Logger?.LogError($"上传昨日数据失败:{ex.Message}{ex.StackTrace}", ex);
                            localTrans.Rollback();

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.Logger?.LogError($"上传昨日数据失败:{ex.Message}{ex.StackTrace}", ex);

            }
            return ret;
        }

        private IEnumerable<YB_PROCESS_STEP> ConvertToProcessStep(List<LocalRecord> localData)
        {
            return localData.AsParallel().Select(T =>
              {
                  if (T.TableName == __TABLE_DwlData)
                  {
                      var dwlData = JsonSerializeHelper.DeserializeObjectFromJson<DwlData>(T.SourceDataJson);
                      return From(dwlData);
                  }
                  else if (T.TableName == __TABLE_LaserData)
                  {
                      var laserData = JsonSerializeHelper.DeserializeObjectFromJson<LaserData>(T.SourceDataJson);
                      return From(laserData);
                  }
                  else
                  {
                      return default(YB_PROCESS_STEP);
                  }

              }).Where(T => T != null).ToList<YB_PROCESS_STEP>();
        }

        public void Dispose()
        {

            GC.SuppressFinalize(this);
        }
        ~LocalDataService()
        {
            GC.SuppressFinalize(this);

        }
    }
}
